from rest_framework.views import APIView
from apps.inform.models import Inform, InformRead
from apps.inform.serializers import InformSerializer
from django.db.models import Q
from django.db.models import Prefetch
from rest_framework.response import Response
from apps.absent.models import Absent
from apps.absent.serializers import AbsentSerializer
from apps.oaauth.models import OADepartment
from django.db.models import Count
from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator


# @cache_page(60*15)
# def cache_demo_view(request):
#     pass


class LatestInformView(APIView):
    """
    返回最新的10条通知
    """

    @method_decorator(cache_page(
        60 * 15))  # 应用了一个装饰器cache_page。这个装饰器是Django提供的缓存机制，cache_page装饰器使得get方法的结果可以被缓存。参数60 * 15表示缓存过期时间为15分钟（60秒 × 15分钟 = 900秒）。
    def get(self, request):
        current_user = request.user  # 通过request.user，我们获取到当前用户的信息。
        # 返回公共的，或者是我所在的部门能看到的通知
        """
        这里使用了Django的ORM来获取通知对象，并使用prefetch_related来优化查询。prefetch_related用于预先加载多对多和一对多关系，以减少数据库查询次数。
        Prefetch对象允许我们定制prefetch_related的行为。这里，我们创建了一个Prefetch对象，用于预先加载每个通知的reads关系，并且通过queryset参数过滤出当前用户读取过的通知。
        Q(public=True) | Q(departments=current_user.department)是一个Django的Q对象，用于提供过滤逻辑，这里表示所有公共的通知或当前用户所在部门的通知。
        [:10]用于限制结果集最多返回10条通知。
        """
        informs = Inform.objects.prefetch_related(
            Prefetch("reads", queryset=InformRead.objects.filter(user_id=current_user.uid)), 'departments').filter(
            Q(public=True) | Q(departments=current_user.department))[:10]
        serializer = InformSerializer(informs,
                                      many=True)  # 创建了一个InformSerializer实例，并将获取到的通知列表传递给它。many=True表示序列化对象是一个列表。
        return Response(serializer.data)  # 最后，get方法返回一个响应，包含序列化后的通知列表。


class LatestAbsentView(APIView):

    @method_decorator(cache_page(60 * 15)) # 应用了一个装饰器cache_page。这个装饰器是Django提供的缓存机制，cache_page装饰器使得get方法的结果可以被缓存。参数60 * 15表示缓存过期时间为15分钟（60秒 × 15分钟 = 900秒）。
    def get(self, request):
        # 董事会的人，可以看到所有人的考勤信息，非董事会的人，只能看到自己部门的考勤信息
        current_user = request.user # 通过request.user，我们获取到当前用户的信息。
        queryset = Absent.objects #  创建了一个Absent模型的查询集。
        if current_user.department.name != '董事会': # 检查当前用户的部门名称是否为董事会。
            queryset = queryset.filter(requester__department_id=current_user.department_id) # 如果用户不是董事会成员，我们添加一个过滤条件到查询集中，只显示requester的部门ID与当前用户部门ID相同的考勤信息。这里的requester__department_id使用了Django的双下划线语法来表示跨模型的字段比较。
        queryset = queryset.all()[:10] # 获取所有符合条件的考勤信息，并限制结果集最多返回10条记录。
        serializer = AbsentSerializer(queryset, many=True)  # 创建了一个AbsentSerializer实例，并将查询集传递给它。many=True表示序列化对象是一个列表。
        return Response(serializer.data) # 最后，get方法返回一个响应，包含序列化后的考勤列表。


class DepartmentStaffCountView(APIView):

    @method_decorator(cache_page(60 * 15)) # 应用了一个装饰器cache_page。这个装饰器是Django提供的缓存机制，cache_page装饰器使得get方法的结果可以被缓存。参数60 * 15表示缓存过期时间为15分钟（60秒 × 15分钟 = 900秒）。
    def get(self, request):
        """
        使用了 Django 的ORM技术，对OADepartment模型进行查询，统计每个部门的员工数量。
        annotate(staff_count=Count("staffs"))会在每个部门的对象上新增一个staff_count字段，表示该部门的员工数量。
        values("name", "staff_count")则指定了查询结果中需要返回的字段，只返回部门名称和员工数量两个字段。
        :param request:
        :return:
        """
        rows = OADepartment.objects.annotate(staff_count=Count("staffs")).values("name", "staff_count") #
        # print(rows)
        print('=' * 10) # 打印分割线，用于控制台调试。
        return Response(rows) # 返回查询结果作为HTTP响应。Django REST framework会自动将查询结果序列化为JSON格式，并设置正确的HTTP状态码（默认为200 OK）。


class HealthCheckView(APIView):
    def get(self, request):
        """
        在get方法中，直接返回一个包含状态码200的JSON响应。
        Django REST framework的Response类用于创建HTTP响应，这里构造了一个表示成功的响应，状态码为200，表示服务器成功处理了请求。
        :param request:
        :return:
        """
        return Response({"code": 200})
